/*
 * File: LEOSIM.c
 *
 * Code generated for Simulink model 'LEOSIM'.
 *
 * Model version                  : 2.717
 * Simulink Coder version         : 9.7 (R2022a) 13-Nov-2021
 * C/C++ source code generated on : Wed Dec 20 13:05:12 2023
 *
 * Target selection: ert.tlc
 * Embedded hardware selection: Intel->x86-64 (Linux 64)
 * Code generation objectives: Unspecified
 * Validation result: Not run
 */

#include "LEOSIM.h"
#include "rtwtypes.h"
#include <math.h>
#include "LEOSIM_private.h"
#include <float.h>

/* Block signals (default storage) */
B_LEOSIM_T LEOSIM_B;

/* Continuous states */
X_LEOSIM_T LEOSIM_X;

/* Block states (default storage) */
DW_LEOSIM_T LEOSIM_DW;

/* External inputs (root inport signals with default storage) */
ExtU_LEOSIM_T LEOSIM_U;

/* External outputs (root outports fed by signals with default storage) */
ExtY_LEOSIM_T LEOSIM_Y;

/* Real-time model */
static RT_MODEL_LEOSIM_T LEOSIM_M_;
RT_MODEL_LEOSIM_T *const LEOSIM_M = &LEOSIM_M_;

/* Lookup 1D UtilityLookUpEven_real32_T_real_T_SAT */
void LookUpEven_real32_T_real_T_SAT(real32_T *pY, const real32_T *pYData, real_T
  u, real_T valueLo, uint32_T iHi, real_T uSpacing)
{
  if (u <= valueLo ) {
    (*pY) = (*pYData);
  } else {
    real_T uAdjusted = (real_T)(u - valueLo);
    real_T tmpIdxLeft = uAdjusted / uSpacing;
    uint64_T iLeft = (uint64_T)tmpIdxLeft;
    if ((tmpIdxLeft >= 18446744073709551616.0) || (iLeft >= iHi) ) {
      (*pY) = pYData[iHi];
    } else {
      {
        real_T lambda;

        {
          real_T num = (real_T)uAdjusted - ( iLeft * uSpacing );
          lambda = num / uSpacing;
        }

        {
          real_T yLeftCast;
          real_T yRghtCast;
          yLeftCast = pYData[iLeft];
          yRghtCast = pYData[((iLeft)+1)];
          yLeftCast += lambda * ( yRghtCast - yLeftCast );
          (*pY) = (real32_T)yLeftCast;
        }
      }
    }
  }
}

real_T look1_binlxpw(real_T u0, const real_T bp0[], const real_T table[],
                     uint32_T maxIndex)
{
  real_T frac;
  real_T yL_0d0;
  uint32_T iLeft;

  /* Column-major Lookup 1-D
     Search method: 'binary'
     Use previous index: 'off'
     Interpolation method: 'Linear point-slope'
     Extrapolation method: 'Linear'
     Use last breakpoint for index at or above upper limit: 'off'
     Remove protection against out-of-range input in generated code: 'off'
   */
  /* Prelookup - Index and Fraction
     Index Search method: 'binary'
     Extrapolation method: 'Linear'
     Use previous index: 'off'
     Use last breakpoint for index at or above upper limit: 'off'
     Remove protection against out-of-range input in generated code: 'off'
   */
  if (u0 <= bp0[0U]) {
    iLeft = 0U;
    frac = (u0 - bp0[0U]) / (bp0[1U] - bp0[0U]);
  } else if (u0 < bp0[maxIndex]) {
    uint32_T bpIdx;
    uint32_T iRght;

    /* Binary Search */
    bpIdx = maxIndex >> 1U;
    iLeft = 0U;
    iRght = maxIndex;
    while (iRght - iLeft > 1U) {
      if (u0 < bp0[bpIdx]) {
        iRght = bpIdx;
      } else {
        iLeft = bpIdx;
      }

      bpIdx = (iRght + iLeft) >> 1U;
    }

    frac = (u0 - bp0[iLeft]) / (bp0[iLeft + 1U] - bp0[iLeft]);
  } else {
    iLeft = maxIndex - 1U;
    frac = (u0 - bp0[maxIndex - 1U]) / (bp0[maxIndex] - bp0[maxIndex - 1U]);
  }

  /* Column-major Interpolation 1-D
     Interpolation method: 'Linear point-slope'
     Use last breakpoint for index at or above upper limit: 'off'
     Overflow mode: 'portable wrapping'
   */
  yL_0d0 = table[iLeft];
  return (table[iLeft + 1U] - yL_0d0) * frac + yL_0d0;
}

real_T look1_binlcapw(real_T u0, const real_T bp0[], const real_T table[],
                      uint32_T maxIndex)
{
  real_T frac;
  real_T y;
  uint32_T iLeft;

  /* Column-major Lookup 1-D
     Search method: 'binary'
     Use previous index: 'off'
     Interpolation method: 'Linear point-slope'
     Extrapolation method: 'Clip'
     Use last breakpoint for index at or above upper limit: 'on'
     Remove protection against out-of-range input in generated code: 'off'
   */
  /* Prelookup - Index and Fraction
     Index Search method: 'binary'
     Extrapolation method: 'Clip'
     Use previous index: 'off'
     Use last breakpoint for index at or above upper limit: 'on'
     Remove protection against out-of-range input in generated code: 'off'
   */
  if (u0 <= bp0[0U]) {
    iLeft = 0U;
    frac = 0.0;
  } else if (u0 < bp0[maxIndex]) {
    uint32_T bpIdx;
    uint32_T iRght;

    /* Binary Search */
    bpIdx = maxIndex >> 1U;
    iLeft = 0U;
    iRght = maxIndex;
    while (iRght - iLeft > 1U) {
      if (u0 < bp0[bpIdx]) {
        iRght = bpIdx;
      } else {
        iLeft = bpIdx;
      }

      bpIdx = (iRght + iLeft) >> 1U;
    }

    frac = (u0 - bp0[iLeft]) / (bp0[iLeft + 1U] - bp0[iLeft]);
  } else {
    iLeft = maxIndex;
    frac = 0.0;
  }

  /* Column-major Interpolation 1-D
     Interpolation method: 'Linear point-slope'
     Use last breakpoint for index at or above upper limit: 'on'
     Overflow mode: 'portable wrapping'
   */
  if (iLeft == maxIndex) {
    y = table[iLeft];
  } else {
    real_T yL_0d0;
    yL_0d0 = table[iLeft];
    y = (table[iLeft + 1U] - yL_0d0) * frac + yL_0d0;
  }

  return y;
}

/*
 * This function updates continuous states using the ODE3 fixed-step
 * solver algorithm
 */
static void rt_ertODEUpdateContinuousStates(RTWSolverInfo *si )
{
  /* Solver Matrices */
  static const real_T rt_ODE3_A[3] = {
    1.0/2.0, 3.0/4.0, 1.0
  };

  static const real_T rt_ODE3_B[3][3] = {
    { 1.0/2.0, 0.0, 0.0 },

    { 0.0, 3.0/4.0, 0.0 },

    { 2.0/9.0, 1.0/3.0, 4.0/9.0 }
  };

  time_T t = rtsiGetT(si);
  time_T tnew = rtsiGetSolverStopTime(si);
  time_T h = rtsiGetStepSize(si);
  real_T *x = rtsiGetContStates(si);
  ODE3_IntgData *id = (ODE3_IntgData *)rtsiGetSolverData(si);
  real_T *y = id->y;
  real_T *f0 = id->f[0];
  real_T *f1 = id->f[1];
  real_T *f2 = id->f[2];
  real_T hB[3];
  int_T i;
  int_T nXc = 4;
  rtsiSetSimTimeStep(si,MINOR_TIME_STEP);

  /* Save the state values at time t in y, we'll use x as ynew. */
  (void) memcpy(y, x,
                (uint_T)nXc*sizeof(real_T));

  /* Assumes that rtsiSetT and ModelOutputs are up-to-date */
  /* f0 = f(t,y) */
  rtsiSetdX(si, f0);
  LEOSIM_derivatives();

  /* f(:,2) = feval(odefile, t + hA(1), y + f*hB(:,1), args(:)(*)); */
  hB[0] = h * rt_ODE3_B[0][0];
  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + (f0[i]*hB[0]);
  }

  rtsiSetT(si, t + h*rt_ODE3_A[0]);
  rtsiSetdX(si, f1);
  LEOSIM_step();
  LEOSIM_derivatives();

  /* f(:,3) = feval(odefile, t + hA(2), y + f*hB(:,2), args(:)(*)); */
  for (i = 0; i <= 1; i++) {
    hB[i] = h * rt_ODE3_B[1][i];
  }

  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + (f0[i]*hB[0] + f1[i]*hB[1]);
  }

  rtsiSetT(si, t + h*rt_ODE3_A[1]);
  rtsiSetdX(si, f2);
  LEOSIM_step();
  LEOSIM_derivatives();

  /* tnew = t + hA(3);
     ynew = y + f*hB(:,3); */
  for (i = 0; i <= 2; i++) {
    hB[i] = h * rt_ODE3_B[2][i];
  }

  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + (f0[i]*hB[0] + f1[i]*hB[1] + f2[i]*hB[2]);
  }

  rtsiSetT(si, tnew);
  rtsiSetSimTimeStep(si,MAJOR_TIME_STEP);
}

real_T rt_remd(real_T u0, real_T u1)
{
  real_T y;
  if ((u1 != 0.0) && (u1 != trunc(u1))) {
    real_T q;
    q = fabs(u0 / u1);
    if (fabs(q - floor(q + 0.5)) <= DBL_EPSILON * q) {
      y = 0.0;
    } else {
      y = fmod(u0, u1);
    }
  } else {
    y = fmod(u0, u1);
  }

  return y;
}

/* Model step function */
void LEOSIM_step(void)
{
  /* local block i/o variables */
  real_T rtb_Gain_a;
  real_T rtb_Add2;
  real_T rtb_Add;
  real_T rtb_DeadZone4;
  real_T rtb_DeadZone5;
  real_T rtb_Max1;
  if (rtmIsMajorTimeStep(LEOSIM_M)) {
    /* set solver stop time */
    rtsiSetSolverStopTime(&LEOSIM_M->solverInfo,((LEOSIM_M->Timing.clockTick0+1)*
      LEOSIM_M->Timing.stepSize0));
  }                                    /* end MajorTimeStep */

  /* Update absolute time of base rate at minor time step */
  if (rtmIsMinorTimeStep(LEOSIM_M)) {
    LEOSIM_M->Timing.t[0] = rtsiGetT(&LEOSIM_M->solverInfo);
  }

  if (rtmIsMajorTimeStep(LEOSIM_M)) {
    /* Gain: '<S143>/Gain' incorporates:
     *  Constant: '<S143>/DebugVehSpd_kmph'
     */
    rtb_Gain_a = 0.27777777777777779 * LEOSIM_P.DebugVehSpd_kmph;

    /* Sum: '<S143>/Add2' incorporates:
     *  Delay: '<S143>/Delay'
     */
    rtb_Add2 = rtb_Gain_a - LEOSIM_DW.Delay_DSTATE;

    /* DiscreteIntegrator: '<S143>/Discrete-Time Integrator2' */
    if (LEOSIM_DW.DiscreteTimeIntegrator2_IC_LOAD != 0) {
      LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = rtb_Gain_a;
      if (LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE >= 60.0) {
        LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = 60.0;
      } else if (LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE <= -15.0) {
        LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = -15.0;
      }
    }

    if ((rtb_Add2 != 0.0) || (LEOSIM_DW.DiscreteTimeIntegrator2_PrevRes != 0)) {
      LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = rtb_Gain_a;
      if (LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE >= 60.0) {
        LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = 60.0;
      } else if (LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE <= -15.0) {
        LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = -15.0;
      }
    }

    if (LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE >= 60.0) {
      LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = 60.0;
    } else if (LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE <= -15.0) {
      LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = -15.0;
    }

    /* Switch: '<S153>/Switch' incorporates:
     *  DiscreteIntegrator: '<S143>/Discrete-Time Integrator2'
     */
    rtb_DeadZone5 = LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE;

    /* DeadZone: '<S143>/Dead Zone' */
    if (rtb_DeadZone5 > 0.1) {
      rtb_DeadZone5 -= 0.1;
    } else if (rtb_DeadZone5 >= -0.1) {
      rtb_DeadZone5 = 0.0;
    } else {
      rtb_DeadZone5 -= -0.1;
    }

    /* End of DeadZone: '<S143>/Dead Zone' */

    /* Gain: '<S102>/1//P_TireRadiu_m' */
    LEOSIM_B.TireSpd_radps = 2.73972602739726 * rtb_DeadZone5;

    /* Lookup_n-D: '<S115>/MotMaxDischargeTrq' incorporates:
     *  Gain: '<S102>/P_MainreduRatio'
     *  Gain: '<S115>/radps2rpm'
     *  Lookup_n-D: '<S115>/MotMaxChargeTrq'
     */
    LEOSIM_B.MotMaxDischargeTrq_Nm = look1_binlxpw(10.5 * LEOSIM_B.TireSpd_radps
      * 9.5492965855137211, LEOSIM_ConstP.pooled14, LEOSIM_ConstP.pooled13, 14U);

    /* Gain: '<S115>/Gain' */
    LEOSIM_B.MotMaxChargeTrq_Nm = -LEOSIM_B.MotMaxDischargeTrq_Nm;

    /* Lookup_n-D: '<S130>/MotMaxDischargeTrq' incorporates:
     *  Gain: '<S102>/P_MainreduRatio1'
     *  Gain: '<S130>/radps2rpm'
     *  Lookup_n-D: '<S130>/MotMaxChargeTrq'
     */
    LEOSIM_B.MotMaxDischargeTrq_Nm_f = look1_binlxpw(9.57 *
      LEOSIM_B.TireSpd_radps * 9.5492965855137211, LEOSIM_ConstP.pooled14,
      LEOSIM_ConstP.pooled13, 14U);

    /* Gain: '<S130>/Gain' */
    LEOSIM_B.MotMaxChargeTrq_Nm_b = -LEOSIM_B.MotMaxDischargeTrq_Nm_f;

    /* DeadZone: '<S145>/Dead Zone' */
    if (rtb_DeadZone5 > 0.1) {
      rtb_DeadZone4 = rtb_DeadZone5 - 0.1;
    } else if (rtb_DeadZone5 >= -0.1) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_DeadZone5 - -0.1;
    }

    /* End of DeadZone: '<S145>/Dead Zone' */

    /* Product: '<S145>/Product' incorporates:
     *  Constant: '<S145>/P_G_mps2'
     *  Constant: '<S145>/P_VehMass_kg'
     *  Constant: '<S145>/P_VehRollForceCoef'
     *  Constant: '<S154>/Constant'
     *  RelationalOperator: '<S154>/Compare'
     */
    LEOSIM_B.Product = rtb_DeadZone4 != 0.0 ? LEOSIM_ConstB.Cos * 2180.0 * 9.81 *
      0.008 : 0.0;

    /* DeadZone: '<S147>/Dead Zone' */
    if (rtb_DeadZone5 > 0.01) {
      rtb_DeadZone4 = rtb_DeadZone5 - 0.01;
    } else if (rtb_DeadZone5 >= -0.01) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_DeadZone5 - -0.01;
    }

    /* End of DeadZone: '<S147>/Dead Zone' */

    /* Gain: '<S147>/Gain1' incorporates:
     *  Constant: '<S147>/P_AirDensity_kgpm3'
     *  Constant: '<S147>/P_VehCd'
     *  Constant: '<S147>/P_VehWindArea_m2'
     *  Math: '<S147>/Math Function'
     *  Product: '<S147>/Product'
     *
     * About '<S147>/Math Function':
     *  Operator: magnitude^2
     */
    LEOSIM_B.Gain1 = rtb_DeadZone4 * rtb_DeadZone4 * 1.2 * 0.24 * 2.66 * 0.5;

    /* Switch: '<S141>/Switch3' incorporates:
     *  Constant: '<S141>/Constant5'
     */
    LEOSIM_B.mu = 0.37;
  }

  /* Saturate: '<S6>/Saturation' incorporates:
   *  Inport: '<Root>/ManualDecelCmd'
   */
  if (LEOSIM_U.ManualDecelCmd > 100.0) {
    rtb_DeadZone4 = 100.0;
  } else if (LEOSIM_U.ManualDecelCmd < 0.0) {
    rtb_DeadZone4 = 0.0;
  } else {
    rtb_DeadZone4 = LEOSIM_U.ManualDecelCmd;
  }

  /* End of Saturate: '<S6>/Saturation' */

  /* Gain: '<S6>/Gain1' incorporates:
   *  Gain: '<S6>/Gain2'
   */
  LEOSIM_Y.BCU_6F_BrkPedlPosn_Rdnt1 = 0.01 * rtb_DeadZone4 * 100.0;

  /* Switch: '<S141>/Switch6' incorporates:
   *  Constant: '<S141>/BCUPButtonBrk'
   */
  if (LEOSIM_ConstB.PSwitchSts) {
    rtb_DeadZone4 = 50.0;
  } else {
    rtb_DeadZone4 = LEOSIM_Y.BCU_6F_BrkPedlPosn_Rdnt1;
  }

  /* End of Switch: '<S141>/Switch6' */

  /* Gain: '<S141>/bar2pa' incorporates:
   *  Constant: '<S141>/Constant'
   *  Lookup_n-D: '<S141>/pedalTravelPressure'
   *  MinMax: '<S141>/Min'
   */
  rtb_DeadZone4 = 100000.0 * fmin(look1_binlcapw(rtb_DeadZone4,
    LEOSIM_ConstP.pedalTravelPressure_bp01Data,
    LEOSIM_ConstP.pedalTravelPressure_tableData, 14U), 200.0);

  /* Gain: '<S141>/Gain' incorporates:
   *  Constant: '<S141>/Constant1'
   *  Constant: '<S141>/Constant8'
   *  Gain: '<S141>/Gain2'
   *  Gain: '<S141>/Gain3'
   *  Product: '<S141>/Product1'
   *  Product: '<S141>/Product2'
   */
  rtb_Add = 2.0 * LEOSIM_B.mu * (0.0012566370614359172 * rtb_DeadZone4) * 0.1315
    / 0.365 * 4.0;

  /* MinMax: '<S141>/Max1' */
  rtb_Max1 = fmax(rtb_Add, LEOSIM_ConstB.uP_TireRadiu_m);
  if (rtmIsMajorTimeStep(LEOSIM_M)) {
    /* Lookup: '<S143>/sign(u)' */
    /*
     * About '<S143>/sign(u)':
     * Input0  Data Type:  Floating Point real_T
     * Output0 Data Type:  Floating Point real32_T
     * Saturation Mode: Saturate
     * Lookup Method: Linear_Endpoint
     *
     * XData is inlined and evenly spaced, so the algorithm only needs
     * the value of the first element, the last element, and the spacing.
     * For efficiency, XData is excluded from the generated code.
     * YData parameter uses the same data type and scaling as Output0
     */
    LookUpEven_real32_T_real_T_SAT( &(LEOSIM_B.signu), LEOSIM_ConstP.signu_YData,
      rtb_DeadZone5, -0.1, 1U, 0.2);
  }

  /* Switch: '<S141>/Switch1' incorporates:
   *  Gain: '<S141>/Gain6'
   *  MinMax: '<S141>/Max'
   *  Switch: '<S141>/Switch'
   *  Switch: '<S141>/Switch2'
   */
  if (LEOSIM_ConstB.Compare) {
    rtb_Add = rtb_Max1;
    rtb_DeadZone4 = fmax(276.10054291132036 * rtb_Max1, rtb_DeadZone4);
  }

  /* End of Switch: '<S141>/Switch1' */

  /* Product: '<S143>/Divide' incorporates:
   *  Constant: '<S143>/P_VehMass_kg'
   *  Gain: '<S102>/P_MainReduRatio'
   *  Gain: '<S102>/P_MainReduRatio1'
   *  Gain: '<S114>/Gain'
   *  Gain: '<S129>/Gain'
   *  Gain: '<S142>/1//P_TireRadiu_m'
   *  Inport: '<Root>/ZONE_2D_TqCmdFA_Rdnt1'
   *  Inport: '<Root>/ZONE_2D_TqCmdRA_Rdnt1'
   *  MinMax: '<S115>/Max'
   *  MinMax: '<S115>/Min'
   *  MinMax: '<S130>/Max'
   *  MinMax: '<S130>/Min'
   *  Product: '<S143>/Product1'
   *  Sum: '<S102>/Add1'
   *  Sum: '<S143>/Add'
   *  Sum: '<S143>/Add1'
   */
  LEOSIM_B.Divide = ((fmax(fmin(0.095238095238095233 *
    LEOSIM_U.ZONE_2D_TqCmdFA_Rdnt1, LEOSIM_B.MotMaxDischargeTrq_Nm),
    LEOSIM_B.MotMaxChargeTrq_Nm) * 10.5 + fmax(fmin(0.1044932079414838 *
    LEOSIM_U.ZONE_2D_TqCmdRA_Rdnt1, LEOSIM_B.MotMaxDischargeTrq_Nm_f),
    LEOSIM_B.MotMaxChargeTrq_Nm_b) * 9.57) * 2.73972602739726 -
                     (((LEOSIM_B.Product + LEOSIM_ConstB.Product) +
                       LEOSIM_B.Gain1) + rtb_Add) * LEOSIM_B.signu) /
    LEOSIM_ConstB.Add / 2180.0;

  /* Outport: '<Root>/ACM_100_LgtA' incorporates:
   *  Gain: '<S62>/Gain'
   *  Switch: '<S152>/Switch'
   */
  LEOSIM_Y.ACM_100_LgtA = 0.1020408163265306 * LEOSIM_B.Divide;

  /* Gain: '<S52>/Gain' incorporates:
   *  Gain: '<S141>/Gain4'
   */
  rtb_DeadZone4 = 1.0E-5 * rtb_DeadZone4 * 100000.0;

  /* Outport: '<Root>/BCU_6F_MCPress_Rdnt1' incorporates:
   *  Gain: '<S2>/PaToBar'
   *  Gain: '<S52>/Gain1'
   */
  LEOSIM_Y.BCU_6F_MCPress_Rdnt1 = 0.1 * rtb_DeadZone4 * 1.0E-5;

  /* Outport: '<Root>/BCU_6F_SCPress_Rdnt1' incorporates:
   *  Gain: '<S2>/PaToBar1'
   */
  LEOSIM_Y.BCU_6F_SCPress_Rdnt1 = 1.0E-5 * rtb_DeadZone4;
  if (rtmIsMajorTimeStep(LEOSIM_M)) {
    /* Gain: '<S28>/Gain3' incorporates:
     *  Gain: '<S2>/Gain'
     *  Gain: '<S2>/Gain1'
     *  Gain: '<S2>/Gain2'
     *  Gain: '<S2>/Gain3'
     *  Gain: '<S32>/Gain3'
     *  Gain: '<S36>/Gain3'
     *  Gain: '<S40>/Gain3'
     */
    rtb_Max1 = 1.314 * LEOSIM_B.TireSpd_radps;

    /* DeadZone: '<S28>/Dead Zone' incorporates:
     *  Gain: '<S28>/Gain3'
     */
    if (rtb_Max1 > 0.5) {
      rtb_DeadZone4 = rtb_Max1 - 0.5;
    } else if (rtb_Max1 >= -0.5) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_Max1 - -0.5;
    }

    /* End of DeadZone: '<S28>/Dead Zone' */

    /* Outport: '<Root>/BCU_6F_WhlSpdDirFL_Rdnt1' incorporates:
     *  Constant: '<S26>/Constant'
     *  Constant: '<S27>/Constant'
     *  DataTypeConversion: '<S2>/Data Type Conversion7'
     *  Gain: '<S17>/Gain2'
     *  RelationalOperator: '<S26>/Compare'
     *  RelationalOperator: '<S27>/Compare'
     *  Sum: '<S17>/Add'
     */
    LEOSIM_Y.BCU_6F_WhlSpdDirFL_Rdnt1 = (int32_T)((((uint32_T)((rtb_DeadZone4 <
      0.0) << 7) << 1) + ((uint32_T)(rtb_DeadZone4 > 0.0) << 7)) >> 7);

    /* DeadZone: '<S32>/Dead Zone' */
    if (rtb_Max1 > 0.5) {
      rtb_DeadZone4 = rtb_Max1 - 0.5;
    } else if (rtb_Max1 >= -0.5) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_Max1 - -0.5;
    }

    /* End of DeadZone: '<S32>/Dead Zone' */

    /* Outport: '<Root>/BCU_6F_WhlSpdDirFR_Rdnt1' incorporates:
     *  Constant: '<S30>/Constant'
     *  Constant: '<S31>/Constant'
     *  DataTypeConversion: '<S2>/Data Type Conversion8'
     *  Gain: '<S20>/Gain2'
     *  RelationalOperator: '<S30>/Compare'
     *  RelationalOperator: '<S31>/Compare'
     *  Sum: '<S20>/Add'
     */
    LEOSIM_Y.BCU_6F_WhlSpdDirFR_Rdnt1 = (int32_T)((((uint32_T)((rtb_DeadZone4 <
      0.0) << 7) << 1) + ((uint32_T)(rtb_DeadZone4 > 0.0) << 7)) >> 7);

    /* DeadZone: '<S36>/Dead Zone' */
    if (rtb_Max1 > 0.5) {
      rtb_DeadZone4 = rtb_Max1 - 0.5;
    } else if (rtb_Max1 >= -0.5) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_Max1 - -0.5;
    }

    /* End of DeadZone: '<S36>/Dead Zone' */

    /* Outport: '<Root>/BCU_6F_WhlSpdDirRL_Rdnt1' incorporates:
     *  Constant: '<S34>/Constant'
     *  Constant: '<S35>/Constant'
     *  DataTypeConversion: '<S2>/Data Type Conversion9'
     *  Gain: '<S23>/Gain2'
     *  RelationalOperator: '<S34>/Compare'
     *  RelationalOperator: '<S35>/Compare'
     *  Sum: '<S23>/Add'
     */
    LEOSIM_Y.BCU_6F_WhlSpdDirRL_Rdnt1 = (int32_T)((((uint32_T)((rtb_DeadZone4 <
      0.0) << 7) << 1) + ((uint32_T)(rtb_DeadZone4 > 0.0) << 7)) >> 7);

    /* DeadZone: '<S40>/Dead Zone' */
    if (rtb_Max1 > 0.5) {
      rtb_DeadZone4 = rtb_Max1 - 0.5;
    } else if (rtb_Max1 >= -0.5) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_Max1 - -0.5;
    }

    /* End of DeadZone: '<S40>/Dead Zone' */

    /* Outport: '<Root>/BCU_6F_WhlSpdDirRR_Rdnt1' incorporates:
     *  Constant: '<S38>/Constant'
     *  Constant: '<S39>/Constant'
     *  DataTypeConversion: '<S2>/Data Type Conversion10'
     *  Gain: '<S24>/Gain2'
     *  RelationalOperator: '<S38>/Compare'
     *  RelationalOperator: '<S39>/Compare'
     *  Sum: '<S24>/Add'
     */
    LEOSIM_Y.BCU_6F_WhlSpdDirRR_Rdnt1 = (int32_T)((((uint32_T)((rtb_DeadZone4 <
      0.0) << 7) << 1) + ((uint32_T)(rtb_DeadZone4 > 0.0) << 7)) >> 7);

    /* DeadZone: '<S2>/Dead Zone' */
    if (rtb_Max1 > 0.5) {
      rtb_DeadZone4 = rtb_Max1 - 0.5;
    } else if (rtb_Max1 >= -0.5) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_Max1 - -0.5;
    }

    /* End of DeadZone: '<S2>/Dead Zone' */

    /* Outport: '<Root>/BCU_6F_WhlSpdFL_Rdnt1' incorporates:
     *  Abs: '<S2>/Abs3'
     */
    LEOSIM_Y.BCU_6F_WhlSpdFL_Rdnt1 = fabs(rtb_DeadZone4);

    /* DeadZone: '<S2>/Dead Zone1' */
    if (rtb_Max1 > 0.5) {
      rtb_DeadZone4 = rtb_Max1 - 0.5;
    } else if (rtb_Max1 >= -0.5) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_Max1 - -0.5;
    }

    /* End of DeadZone: '<S2>/Dead Zone1' */

    /* Outport: '<Root>/BCU_6F_WhlSpdFR_Rdnt1' incorporates:
     *  Abs: '<S2>/Abs2'
     */
    LEOSIM_Y.BCU_6F_WhlSpdFR_Rdnt1 = fabs(rtb_DeadZone4);

    /* DeadZone: '<S2>/Dead Zone2' */
    if (rtb_Max1 > 0.5) {
      rtb_DeadZone4 = rtb_Max1 - 0.5;
    } else if (rtb_Max1 >= -0.5) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_Max1 - -0.5;
    }

    /* End of DeadZone: '<S2>/Dead Zone2' */

    /* Outport: '<Root>/BCU_6F_WhlSpdRL_Rdnt1' incorporates:
     *  Abs: '<S2>/Abs1'
     */
    LEOSIM_Y.BCU_6F_WhlSpdRL_Rdnt1 = fabs(rtb_DeadZone4);

    /* DeadZone: '<S2>/Dead Zone3' */
    if (rtb_Max1 > 0.5) {
      rtb_DeadZone4 = rtb_Max1 - 0.5;
    } else if (rtb_Max1 >= -0.5) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_Max1 - -0.5;
    }

    /* End of DeadZone: '<S2>/Dead Zone3' */

    /* Outport: '<Root>/BCU_6F_WhlSpdRR_Rdnt1' incorporates:
     *  Abs: '<S2>/Abs'
     */
    LEOSIM_Y.BCU_6F_WhlSpdRR_Rdnt1 = fabs(rtb_DeadZone4);

    /* Gain: '<S2>/Gain4' incorporates:
     *  Gain: '<S2>/Gain5'
     */
    rtb_DeadZone5 *= 3.6;

    /* DeadZone: '<S2>/Dead Zone4' incorporates:
     *  Gain: '<S2>/Gain4'
     */
    if (rtb_DeadZone5 > 0.5) {
      rtb_DeadZone4 = rtb_DeadZone5 - 0.5;
    } else if (rtb_DeadZone5 >= -0.5) {
      rtb_DeadZone4 = 0.0;
    } else {
      rtb_DeadZone4 = rtb_DeadZone5 - -0.5;
    }

    /* End of DeadZone: '<S2>/Dead Zone4' */

    /* Outport: '<Root>/BCU_11F_VehSpd_ASILD' incorporates:
     *  Abs: '<S2>/Abs5'
     */
    LEOSIM_Y.BCU_11F_VehSpd_ASILD = fabs(rtb_DeadZone4);

    /* DeadZone: '<S2>/Dead Zone5' */
    if (rtb_DeadZone5 > 0.5) {
      rtb_DeadZone5 -= 0.5;
    } else if (rtb_DeadZone5 >= -0.5) {
      rtb_DeadZone5 = 0.0;
    } else {
      rtb_DeadZone5 -= -0.5;
    }

    /* End of DeadZone: '<S2>/Dead Zone5' */

    /* Outport: '<Root>/BCU_11E_VehSpd_Rdnt1' incorporates:
     *  Abs: '<S2>/Abs4'
     */
    LEOSIM_Y.BCU_11E_VehSpd_Rdnt1 = fabs(rtb_DeadZone5);
  }

  /* Outport: '<Root>/BCU_6F_WhlPlsCntRL_Rdnt1' incorporates:
   *  Constant: '<S18>/Constant1'
   *  Gain: '<S18>/Gain'
   *  Integrator: '<S18>/Integrator'
   *  Math: '<S18>/Math Function'
   *  Rounding: '<S18>/Floor'
   */
  LEOSIM_Y.BCU_6F_WhlPlsCntRL_Rdnt1 = floor(40.58451048843331 * rt_remd
    (LEOSIM_X.Integrator_CSTATE, 6.2831853071795862));

  /* Outport: '<Root>/BCU_6F_WhlPlsCntRR_Rdnt1' incorporates:
   *  Constant: '<S19>/Constant1'
   *  Gain: '<S19>/Gain'
   *  Integrator: '<S19>/Integrator'
   *  Math: '<S19>/Math Function'
   *  Rounding: '<S19>/Floor'
   */
  LEOSIM_Y.BCU_6F_WhlPlsCntRR_Rdnt1 = floor(40.58451048843331 * rt_remd
    (LEOSIM_X.Integrator_CSTATE_d, 6.2831853071795862));

  /* Outport: '<Root>/BCU_6F_WhlPlsCntFL_Rdnt1' incorporates:
   *  Constant: '<S21>/Constant1'
   *  Gain: '<S21>/Gain'
   *  Integrator: '<S21>/Integrator'
   *  Math: '<S21>/Math Function'
   *  Rounding: '<S21>/Floor'
   */
  LEOSIM_Y.BCU_6F_WhlPlsCntFL_Rdnt1 = floor(40.58451048843331 * rt_remd
    (LEOSIM_X.Integrator_CSTATE_c, 6.2831853071795862));

  /* Outport: '<Root>/BCU_6F_WhlPlsCntFR_Rdnt1' incorporates:
   *  Constant: '<S22>/Constant1'
   *  Gain: '<S22>/Gain'
   *  Integrator: '<S22>/Integrator'
   *  Math: '<S22>/Math Function'
   *  Rounding: '<S22>/Floor'
   */
  LEOSIM_Y.BCU_6F_WhlPlsCntFR_Rdnt1 = floor(40.58451048843331 * rt_remd
    (LEOSIM_X.Integrator_CSTATE_k, 6.2831853071795862));
  if (rtmIsMajorTimeStep(LEOSIM_M)) {
    if (rtmIsMajorTimeStep(LEOSIM_M)) {
      /* Update for Delay: '<S143>/Delay' */
      LEOSIM_DW.Delay_DSTATE = rtb_Gain_a;

      /* Update for DiscreteIntegrator: '<S143>/Discrete-Time Integrator2' */
      LEOSIM_DW.DiscreteTimeIntegrator2_IC_LOAD = 0U;
      LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE += 0.001 * LEOSIM_B.Divide;
      if (LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE >= 60.0) {
        LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = 60.0;
      } else if (LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE <= -15.0) {
        LEOSIM_DW.DiscreteTimeIntegrator2_DSTATE = -15.0;
      }

      if (rtb_Add2 > 0.0) {
        LEOSIM_DW.DiscreteTimeIntegrator2_PrevRes = 1;
      } else if (rtb_Add2 < 0.0) {
        LEOSIM_DW.DiscreteTimeIntegrator2_PrevRes = -1;
      } else if (rtb_Add2 == 0.0) {
        LEOSIM_DW.DiscreteTimeIntegrator2_PrevRes = 0;
      } else {
        LEOSIM_DW.DiscreteTimeIntegrator2_PrevRes = 2;
      }

      /* End of Update for DiscreteIntegrator: '<S143>/Discrete-Time Integrator2' */
    }
  }                                    /* end MajorTimeStep */

  if (rtmIsMajorTimeStep(LEOSIM_M)) {
    rt_ertODEUpdateContinuousStates(&LEOSIM_M->solverInfo);

    /* Update absolute time for base rate */
    /* The "clockTick0" counts the number of times the code of this task has
     * been executed. The absolute time is the multiplication of "clockTick0"
     * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
     * overflow during the application lifespan selected.
     */
    ++LEOSIM_M->Timing.clockTick0;
    LEOSIM_M->Timing.t[0] = rtsiGetSolverStopTime(&LEOSIM_M->solverInfo);

    {
      /* Update absolute timer for sample time: [0.001s, 0.0s] */
      /* The "clockTick1" counts the number of times the code of this task has
       * been executed. The resolution of this integer timer is 0.001, which is the step size
       * of the task. Size of "clockTick1" ensures timer will not overflow during the
       * application lifespan selected.
       */
      LEOSIM_M->Timing.clockTick1++;
    }
  }                                    /* end MajorTimeStep */
}

/* Derivatives for root system: '<Root>' */
void LEOSIM_derivatives(void)
{
  XDot_LEOSIM_T *_rtXdot;
  _rtXdot = ((XDot_LEOSIM_T *) LEOSIM_M->derivs);

  /* Derivatives for Integrator: '<S18>/Integrator' */
  _rtXdot->Integrator_CSTATE = LEOSIM_B.TireSpd_radps;

  /* Derivatives for Integrator: '<S19>/Integrator' */
  _rtXdot->Integrator_CSTATE_d = LEOSIM_B.TireSpd_radps;

  /* Derivatives for Integrator: '<S21>/Integrator' */
  _rtXdot->Integrator_CSTATE_c = LEOSIM_B.TireSpd_radps;

  /* Derivatives for Integrator: '<S22>/Integrator' */
  _rtXdot->Integrator_CSTATE_k = LEOSIM_B.TireSpd_radps;
}

/* Model initialize function */
void LEOSIM_initialize(void)
{
  /* Registration code */
  {
    /* Setup solver object */
    rtsiSetSimTimeStepPtr(&LEOSIM_M->solverInfo, &LEOSIM_M->Timing.simTimeStep);
    rtsiSetTPtr(&LEOSIM_M->solverInfo, &rtmGetTPtr(LEOSIM_M));
    rtsiSetStepSizePtr(&LEOSIM_M->solverInfo, &LEOSIM_M->Timing.stepSize0);
    rtsiSetdXPtr(&LEOSIM_M->solverInfo, &LEOSIM_M->derivs);
    rtsiSetContStatesPtr(&LEOSIM_M->solverInfo, (real_T **)
                         &LEOSIM_M->contStates);
    rtsiSetNumContStatesPtr(&LEOSIM_M->solverInfo,
      &LEOSIM_M->Sizes.numContStates);
    rtsiSetNumPeriodicContStatesPtr(&LEOSIM_M->solverInfo,
      &LEOSIM_M->Sizes.numPeriodicContStates);
    rtsiSetPeriodicContStateIndicesPtr(&LEOSIM_M->solverInfo,
      &LEOSIM_M->periodicContStateIndices);
    rtsiSetPeriodicContStateRangesPtr(&LEOSIM_M->solverInfo,
      &LEOSIM_M->periodicContStateRanges);
    rtsiSetErrorStatusPtr(&LEOSIM_M->solverInfo, (&rtmGetErrorStatus(LEOSIM_M)));
    rtsiSetRTModelPtr(&LEOSIM_M->solverInfo, LEOSIM_M);
  }

  rtsiSetSimTimeStep(&LEOSIM_M->solverInfo, MAJOR_TIME_STEP);
  LEOSIM_M->intgData.y = LEOSIM_M->odeY;
  LEOSIM_M->intgData.f[0] = LEOSIM_M->odeF[0];
  LEOSIM_M->intgData.f[1] = LEOSIM_M->odeF[1];
  LEOSIM_M->intgData.f[2] = LEOSIM_M->odeF[2];
  LEOSIM_M->contStates = ((X_LEOSIM_T *) &LEOSIM_X);
  rtsiSetSolverData(&LEOSIM_M->solverInfo, (void *)&LEOSIM_M->intgData);
  rtsiSetIsMinorTimeStepWithModeChange(&LEOSIM_M->solverInfo, false);
  rtsiSetSolverName(&LEOSIM_M->solverInfo,"ode3");
  rtmSetTPtr(LEOSIM_M, &LEOSIM_M->Timing.tArray[0]);
  LEOSIM_M->Timing.stepSize0 = 0.001;

  /* InitializeConditions for DiscreteIntegrator: '<S143>/Discrete-Time Integrator2' */
  LEOSIM_DW.DiscreteTimeIntegrator2_IC_LOAD = 1U;

  /* InitializeConditions for Integrator: '<S18>/Integrator' */
  LEOSIM_X.Integrator_CSTATE = 0.0;

  /* InitializeConditions for Integrator: '<S19>/Integrator' */
  LEOSIM_X.Integrator_CSTATE_d = 0.0;

  /* InitializeConditions for Integrator: '<S21>/Integrator' */
  LEOSIM_X.Integrator_CSTATE_c = 0.0;

  /* InitializeConditions for Integrator: '<S22>/Integrator' */
  LEOSIM_X.Integrator_CSTATE_k = 0.0;
}

/* Model terminate function */
void LEOSIM_terminate(void)
{
  /* (no terminate code required) */
}

/*
 * File trailer for generated code.
 *
 * [EOF]
 */
